package database

import (
	"changeme/internal/models"
	"strconv"
)

// Factory 数据库驱动工厂实现
type Factory struct {
	drivers     map[models.DatabaseType]func() DatabaseDriver
	middlewares []Middleware
}

// NewFactory 创建驱动工厂实例
func NewFactory() *Factory {
	factory := &Factory{
		drivers:     make(map[models.DatabaseType]func() DatabaseDriver),
		middlewares: make([]Middleware, 0),
	}

	// 注册支持的数据库驱动
	factory.RegisterDriver(models.MySQL, func() DatabaseDriver {
		return NewMySQLDriver()
	})

	factory.RegisterDriver(models.PostgreSQL, func() DatabaseDriver {
		return NewPostgreSQLDriver()
	})

	factory.RegisterDriver(models.SQLite, func() DatabaseDriver {
		return NewSQLiteDriverImpl()
	})

	factory.RegisterDriver(models.SQLServer, func() DatabaseDriver {
		return NewSQLServerDriverImpl()
	})

	factory.RegisterDriver(models.DaMeng, func() DatabaseDriver {
		return NewDaMengDriver()
	})

	return factory
}

// RegisterDriver 注册数据库驱动
func (f *Factory) RegisterDriver(dbType models.DatabaseType, creator func() DatabaseDriver) {
	f.drivers[dbType] = creator
}

// AddMiddleware 添加中间件
func (f *Factory) AddMiddleware(middleware Middleware) {
	f.middlewares = append(f.middlewares, middleware)
}

// CreateDriver 创建数据库驱动
func (f *Factory) CreateDriver(dbType models.DatabaseType) (DatabaseDriver, error) {
	creator, exists := f.drivers[dbType]
	if !exists {
		return nil, ErrUnsupportedDatabase
	}

	driver := creator()

	// 应用中间件
	for i := len(f.middlewares) - 1; i >= 0; i-- {
		driver = f.middlewares[i](driver)
	}

	return driver, nil
}

// SupportedTypes 获取支持的数据库类型
func (f *Factory) SupportedTypes() []models.DatabaseType {
	types := make([]models.DatabaseType, 0, len(f.drivers))
	for dbType := range f.drivers {
		types = append(types, dbType)
	}
	return types
}

// IsSupported 检查是否支持指定的数据库类型
func (f *Factory) IsSupported(dbType models.DatabaseType) bool {
	_, exists := f.drivers[dbType]
	return exists
}

// GetDriverInfo 获取驱动信息
func (f *Factory) GetDriverInfo() map[models.DatabaseType]map[string]interface{} {
	info := make(map[models.DatabaseType]map[string]interface{})

	info[models.MySQL] = map[string]interface{}{
		"name":         "MySQL",
		"description":  "MySQL database driver",
		"default_port": 3306,
		"features":     []string{"transactions", "indexes", "foreign_keys", "views", "procedures"},
	}

	info[models.PostgreSQL] = map[string]interface{}{
		"name":         "PostgreSQL",
		"description":  "PostgreSQL database driver",
		"default_port": 5432,
		"features":     []string{"transactions", "indexes", "foreign_keys", "views", "procedures", "json", "arrays"},
	}

	info[models.SQLite] = map[string]interface{}{
		"name":         "SQLite",
		"description":  "SQLite database driver",
		"default_port": 0,
		"features":     []string{"transactions", "indexes", "foreign_keys", "views", "triggers"},
	}

	info[models.SQLServer] = map[string]interface{}{
		"name":         "SQL Server",
		"description":  "Microsoft SQL Server database driver",
		"default_port": 1433,
		"features":     []string{"transactions", "indexes", "foreign_keys", "views", "procedures", "functions"},
	}

	return info
}

// 占位符方言实现

// PostgreSQLDialect PostgreSQL方言
type PostgreSQLDialect struct{}

func (d *PostgreSQLDialect) QuoteIdentifier(identifier string) string {
	return `"` + identifier + `"`
}

func (d *PostgreSQLDialect) QuoteString(str string) string {
	return "'" + str + "'"
}

func (d *PostgreSQLDialect) GetDataTypeMapping() map[string]string {
	return map[string]string{
		"varchar": "VARCHAR",
		"text":    "TEXT",
		"integer": "INTEGER",
		"bigint":  "BIGINT",
		"decimal": "DECIMAL",
		"real":    "REAL",
		"boolean": "BOOLEAN",
		"json":    "JSON",
		"jsonb":   "JSONB",
	}
}

func (d *PostgreSQLDialect) GetLimitClause(limit, offset int) string {
	if offset > 0 {
		return "LIMIT " + strconv.Itoa(limit) + " OFFSET " + strconv.Itoa(offset)
	}
	return "LIMIT " + strconv.Itoa(limit)
}

func (d *PostgreSQLDialect) GetCurrentTimeFunction() string {
	return "NOW()"
}

func (d *PostgreSQLDialect) GetAutoIncrementClause() string {
	return "SERIAL"
}

// SQLiteDialect SQLite方言
type SQLiteDialect struct{}

func (d *SQLiteDialect) QuoteIdentifier(identifier string) string {
	return `"` + identifier + `"`
}

func (d *SQLiteDialect) QuoteString(str string) string {
	return "'" + str + "'"
}

func (d *SQLiteDialect) GetDataTypeMapping() map[string]string {
	return map[string]string{
		"text":    "TEXT",
		"integer": "INTEGER",
		"real":    "REAL",
		"blob":    "BLOB",
	}
}

func (d *SQLiteDialect) GetLimitClause(limit, offset int) string {
	if offset > 0 {
		return "LIMIT " + strconv.Itoa(limit) + " OFFSET " + strconv.Itoa(offset)
	}
	return "LIMIT " + strconv.Itoa(limit)
}

func (d *SQLiteDialect) GetCurrentTimeFunction() string {
	return "datetime('now')"
}

func (d *SQLiteDialect) GetAutoIncrementClause() string {
	return "AUTOINCREMENT"
}

// SQLServerDialect SQL Server方言
type SQLServerDialect struct{}

func (d *SQLServerDialect) QuoteIdentifier(identifier string) string {
	return "[" + identifier + "]"
}

func (d *SQLServerDialect) QuoteString(str string) string {
	return "'" + str + "'"
}

func (d *SQLServerDialect) GetDataTypeMapping() map[string]string {
	return map[string]string{
		"varchar":  "VARCHAR",
		"nvarchar": "NVARCHAR",
		"text":     "TEXT",
		"int":      "INT",
		"bigint":   "BIGINT",
		"decimal":  "DECIMAL",
		"float":    "FLOAT",
		"bit":      "BIT",
		"datetime": "DATETIME",
	}
}

func (d *SQLServerDialect) GetLimitClause(limit, offset int) string {
	if offset > 0 {
		return "OFFSET " + strconv.Itoa(offset) + " ROWS FETCH NEXT " + strconv.Itoa(limit) + " ROWS ONLY"
	}
	return "TOP " + strconv.Itoa(limit)
}

func (d *SQLServerDialect) GetCurrentTimeFunction() string {
	return "GETDATE()"
}

func (d *SQLServerDialect) GetAutoIncrementClause() string {
	return "IDENTITY(1,1)"
}
